package com.zhdl.modules.prefiresys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.project.common.service.impl.BaseServiceImpl;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.zhdl.common.ytools.DateTimeHelper;
import com.zhdl.common.ytools.EnumHelper;
import com.zhdl.modules.prefiresys.entity.*;
import com.zhdl.modules.prefiresys.repository.DefAreaAlarmRecRepository;
import com.zhdl.modules.prefiresys.service.DefAreaAlarmRecService;
import com.zhdl.modules.prefiresys.web.request.AlarmRecListRequest;
import com.zhdl.modules.prefiresys.web.request.EventAlarmInfoReq;
import com.zhdl.modules.prefiresys.web.response.AlarmRecListQueryResult;
import com.zhdl.modules.prefiresys.web.response.AlarmRecListResp;
import com.zhdl.modules.prefiresys.web.response.EventAlarmInfoListQueryResult;
import com.zhdl.modules.prefiresys.web.response.EventAlarmInfoResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 报警记录
 */
@Slf4j
@Service
public class DefAreaAlarmRecServiceImpl extends BaseServiceImpl<String, DefAreaAlarmRec, DefAreaAlarmRecRepository> implements DefAreaAlarmRecService {


    @Autowired
    private JPAQueryFactory jpaQueryFactory;

    /**
     * 通过事件查询报警信息
     */
    @Override
    public Page<EventAlarmInfoResp> findAlarmRecordsByEventId(EventAlarmInfoReq request, Pageable pageable){
        QEventRecords qEventRecords = QEventRecords.eventRecords;
        QDefAreaAlarmRec qAlarmRec = QDefAreaAlarmRec.defAreaAlarmRec;

        JPAQuery<EventAlarmInfoListQueryResult> query = jpaQueryFactory
                .select(Projections.constructor(EventAlarmInfoListQueryResult.class
                        ,qAlarmRec.id
                        ,qAlarmRec.alarmStatus
                        ,qAlarmRec.startTime
                        ,qAlarmRec.endTime
                        ,qAlarmRec.smokePercent
                        ,qAlarmRec.particlePercent
                        ))
                .from(qAlarmRec)
                .where(qEventRecords.id.eq(request.getEventId()));

        long total = query.fetchCount();

        List<EventAlarmInfoListQueryResult> fetch = query
                .orderBy(qAlarmRec.startTime.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

        List<EventAlarmInfoResp> responses = new ArrayList<>();

        fetch.forEach(item -> {
            EventAlarmInfoResp recListResp = new EventAlarmInfoResp();
            BeanUtil.copyProperties(item, recListResp, CopyOptions.create().setIgnoreNullValue(true));
            responses.add(recListResp);
        });

        return new PageImpl<>(responses, pageable, total);
    }

    /**
     * 查询所有报警记录
     *
     * @return
     */
    @Override
    public Page<AlarmRecListResp> findAllRecord(AlarmRecListRequest request, Pageable pageable) {

        QDefAreaAlarmRec qAlarmRec = QDefAreaAlarmRec.defAreaAlarmRec;
        QDetectorAreaInfo qDetectorAreaInfo = QDetectorAreaInfo.detectorAreaInfo;
        QDetector qDetector = QDetector.detector;

        BooleanBuilder builder = new BooleanBuilder();
        //查找时间范围段内的信息
        builder.and(qAlarmRec.startTime.between(request.getStartTime(), request.getEndTime()));

        if (request.getDetectorId().size() > 0) {
            BooleanBuilder builder1 = new BooleanBuilder();
            for (String id : request.getDetectorId())
                builder1.or(qAlarmRec.detectorId.eq(id));

            builder.and(builder1);
        }
        if (request.getAreaId().size() > 0) {
            BooleanBuilder builder1 = new BooleanBuilder();
            for (String id : request.getAreaId())
                builder1.or(qAlarmRec.areaId.eq(id));

            builder.and(builder1);
        }

        if (request.getAlarmStatus().size() > 0) {
            BooleanBuilder builder1 = new BooleanBuilder();
            for (byte id : request.getAlarmStatus())
                builder1.or(qAlarmRec.nextAlarmStatus.eq(id));

            builder.and(builder1);
        }

        JPAQuery<AlarmRecListQueryResult> query = jpaQueryFactory
                .select(Projections.constructor(AlarmRecListQueryResult.class,
                        qAlarmRec.id,
                        qAlarmRec.nextAlarmStatus,
                        qAlarmRec.startTime,
                        qAlarmRec.endTime,
                        qAlarmRec.durationSec,
                        qDetector.detectorNo,
                        qDetector.detectorName.as("detectorName"),
                        qDetectorAreaInfo.areaName,
                        qAlarmRec.smokePercent,
                        qAlarmRec.particlePercent))
                .from(qAlarmRec)
                .leftJoin(qDetectorAreaInfo).on(qDetectorAreaInfo.id.eq(qAlarmRec.areaId))
                .leftJoin(qDetector).on(qDetector.id.eq(qAlarmRec.detectorId))
                .where(builder);

//        query.leftJoin(qDetectorAreaInfo).on(qDetectorAreaInfo.id.eq(qAlarmRec.areaId));
//        query.leftJoin(qDetector).on(qDetector.id.eq(qAlarmRec.detectorId));

        long total = query.fetchCount();

        List<AlarmRecListQueryResult> fetch = query
                .orderBy(qAlarmRec.createDate.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

//        long total = jpaQueryFactory().select(qAlarmRec.count()).from(qAlarmRec).
//                where(builder).fetchOne();


        List<AlarmRecListResp> responses = new ArrayList<>();

        fetch.forEach(item -> {
            AlarmRecListResp recListResp = new AlarmRecListResp();
            BeanUtil.copyProperties(item, recListResp, CopyOptions.create().setIgnoreNullValue(true));
            recListResp.setDurationSec(DateTimeHelper.secondToTimeString(item.getDurationSec()));
            recListResp.setAlarmStatus(EnumHelper.getAlarmStatusDesc(item.getAlarmStatus()));
            responses.add(recListResp);
        });

        return new PageImpl<>(responses, pageable, total);

    }

    /**
     * 统计近七日报警数据总数
     *
     * @return
     */
    @Override
    public List<Object[]> statAgoWeekAlarmCount() {
        return repository.statAgoWeekAlarmCount();
    }

    /**
     * 查询七天内的报警信息
     * 两次正常算一次 所以 当报警为0或者-1时，为一次报警
     *
     * @return
     */
    @Override
    public List<Object[]> statAgoWeekAlarmCount_1() {
        return repository.statAgoWeekAlarmCount_1();
    }

    @Override
    public DefAreaAlarmRec findNewRecords() {
        return repository.findNewData();
    }

    /**
     * 统计最近一个月各等级报警数据
     */
    public List<Object[]> statMonthAlarmNo1() {
        return repository.statMonthAlarmNo1();
    }

    public List<Object[]> statMonthAlarmNo2() {
        return repository.statMonthAlarmNo2();
    }

    public List<Object[]> statMonthAlarmNo3() {
        return repository.statMonthAlarmNo3();
    }

}
